package com.smart.community.commons.websocket.interceptor;

import com.smart.community.commons.websocket.security.WebSocketSecurityManager;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.HandshakeInterceptor;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;

import java.util.Map;

/**
 * WebSocket拦截器
 * 
 * @author Wu.Liang
 * @since 2025-01-30
 */
@Component
@Slf4j
public class WebSocketInterceptor implements HandshakeInterceptor {

    @Autowired
    private WebSocketSecurityManager securityManager;

    @Override
    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response,
                                   WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
        
        try {
            // 获取客户端IP
            String clientIp = getClientIp(request);
            
            // 获取用户信息（从请求头或参数中）
            Long userId = getUserIdFromRequest(request);
            String username = getUsernameFromRequest(request);
            String userType = getUserTypeFromRequest(request);
            Long propertyCompanyId = getPropertyCompanyIdFromRequest(request);

            // 验证连接权限
            WebSocketSecurityManager.SecurityValidationResult result = 
                securityManager.validateConnection(userId, username, userType, propertyCompanyId, clientIp);
            
            if (result.isValid()) {
                // 设置用户信息到会话属性
                attributes.put("userId", userId);
                attributes.put("username", username);
                attributes.put("userType", userType);
                attributes.put("propertyCompanyId", propertyCompanyId);
                attributes.put("clientIp", clientIp);

                log.info("WebSocket连接验证通过，用户ID: {}, 用户名: {}, IP: {}", userId, username, clientIp);
                return true;
            } else {
                log.warn("WebSocket连接验证失败，用户ID: {}, 原因: {}", userId, result.getReason());
                return false;
            }

        } catch (Exception e) {
            log.error("WebSocket连接验证异常，错误: {}", e.getMessage(), e);
            return false;
        }
    }

    @Override
    public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response,
                              WebSocketHandler wsHandler, Exception exception) {
        
        if (exception != null) {
            log.error("WebSocket握手后处理失败，错误: {}", exception.getMessage(), exception);
        } else {
            log.debug("WebSocket握手完成");
        }
    }

    /**
     * 获取客户端IP地址
     */
    private String getClientIp(ServerHttpRequest request) {
        String clientIp = request.getHeaders().getFirst("X-Forwarded-For");
        if (clientIp == null) {
            clientIp = request.getHeaders().getFirst("X-Real-IP");
        }
        if (clientIp == null) {
            clientIp = request.getHeaders().getFirst("X-Client-IP");
        }
        if (clientIp == null) {
            clientIp = request.getRemoteAddress().getAddress().getHostAddress();
        }
        return clientIp;
    }

    /**
     * 从请求中获取用户ID
     */
    private Long getUserIdFromRequest(ServerHttpRequest request) {
        // 从请求头获取
        String userIdStr = request.getHeaders().getFirst("X-User-Id");
        if (userIdStr != null) {
            try {
                return Long.parseLong(userIdStr);
            } catch (NumberFormatException e) {
                log.warn("无效的用户ID格式: {}", userIdStr);
            }
        }
        
        // 从查询参数获取
        String userIdParam = request.getURI().getQuery();
        if (userIdParam != null && userIdParam.contains("userId=")) {
            String[] params = userIdParam.split("&");
            for (String param : params) {
                if (param.startsWith("userId=")) {
                    try {
                        return Long.parseLong(param.substring(7));
                    } catch (NumberFormatException e) {
                        log.warn("无效的用户ID格式: {}", param.substring(7));
                    }
                }
            }
        }
        
        // 临时返回默认值，实际项目中应该从Token中解析
        return 1L;
    }

    /**
     * 从请求中获取用户名
     */
    private String getUsernameFromRequest(ServerHttpRequest request) {
        String username = request.getHeaders().getFirst("X-Username");
        if (username != null) {
            return username;
        }
        
        // 临时返回默认值，实际项目中应该从Token中解析
        return "test_user";
    }

    /**
     * 从请求中获取用户类型
     */
    private String getUserTypeFromRequest(ServerHttpRequest request) {
        String userType = request.getHeaders().getFirst("X-User-Type");
        if (userType != null) {
            return userType;
        }
        
        // 临时返回默认值，实际项目中应该从Token中解析
        return "admin";
    }

    /**
     * 从请求中获取物业公司ID
     */
    private Long getPropertyCompanyIdFromRequest(ServerHttpRequest request) {
        String companyIdStr = request.getHeaders().getFirst("X-Property-Company-Id");
        if (companyIdStr != null) {
            try {
                return Long.parseLong(companyIdStr);
            } catch (NumberFormatException e) {
                log.warn("无效的物业公司ID格式: {}", companyIdStr);
            }
        }
        
        // 临时返回默认值，实际项目中应该从Token中解析
        return 1L;
    }
}
